package fi.piet.ec2.dao.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.wicket.spring.injection.annot.SpringBean;

import com.xerox.amazonws.sdb.Domain;
import com.xerox.amazonws.sdb.Item;
import com.xerox.amazonws.sdb.ItemAttribute;
import com.xerox.amazonws.sdb.QueryResult;
import com.xerox.amazonws.sdb.QueryWithAttributesResult;
import com.xerox.amazonws.sdb.SDBException;
import com.xerox.amazonws.sdb.SimpleDB;

import fi.piet.ec2.dao.DepartmentDao;
import fi.piet.ec2.dao.EmployeeDao;
import fi.piet.ec2.department.Department;
import fi.piet.ec2.employee.Employee;

public class EmployeeDaoSDB implements EmployeeDao {

	private String awsAccessId;
	private String awsSecretKey;

	@SpringBean
	private DepartmentDao depDao;

	public Employee findEmployeeByName(String lastname, String firstname) {
		// TODO Auto-generated method stub
		return null;
	}

	public List<Employee> getAllEmployees() {
		SimpleDB sdb = new SimpleDB(awsAccessId, awsSecretKey);
		Domain empDomain;

		List<Item> items = null;
		List<Employee> empList = new ArrayList<Employee>();

		QueryResult result = null;

		try {
			empDomain = sdb.getDomain("employees");
			result = empDomain.listItems();
			items = result.getItemList();

			for (Item item : items) {
				empList.add(createEmployee(item));
			}

		} catch (SDBException ex) {
			System.err.println("message : " + ex.getMessage());
			System.err.println("requestID : " + ex.getRequestId());
		}

		return empList;
	}


	public void storeEmployee(Employee emp) {

		String uuId = emp.getId();
		if (uuId == null) {
			uuId = java.util.UUID.randomUUID().toString();
		}

		SimpleDB sdb = new SimpleDB(awsAccessId, awsSecretKey);
		Item empItem;
		List<ItemAttribute> attributes;
		Domain employeeDomain;
		try {
			employeeDomain = sdb.getDomain("employees");

			empItem = employeeDomain.getItem(uuId);
			
			attributes = new ArrayList<ItemAttribute>();
			attributes.add(new ItemAttribute("firstname", emp.getFirstname(), true));
			attributes.add(new ItemAttribute("lastname", emp.getLastname(), true));
			attributes.add(new ItemAttribute("department", emp.getDepartment().getId(), true));

			empItem.putAttributes(attributes);

		} catch (SDBException ex) {
			System.err.println("message : " + ex.getMessage());
			System.err.println("requestID : " + ex.getRequestId());
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<Employee> findEmployeesForADepartment(String depId) {

		SimpleDB sdb = new SimpleDB(awsAccessId, awsSecretKey);
		Domain empDomain;

		Map<String,List<ItemAttribute>> items = null;
		List<Employee> empList = new ArrayList<Employee>();

		QueryWithAttributesResult result = null;

		try {
			empDomain = sdb.getDomain("employees");
			result = empDomain.selectItems("select * from employees where department = '" + depId + "'", null);
			items = result.getItems();

		    Iterator<?> it = items.entrySet().iterator();
		    while (it.hasNext()) {
		        Map.Entry pairs = (Map.Entry)it.next();
		        
		        Employee emp = createEmployee((List<ItemAttribute>) pairs.getValue());
		        emp.setId(pairs.getKey().toString());

		        empList.add(emp);
		    }

		} catch (SDBException ex) {
			System.err.println("message : " + ex.getMessage());
			System.err.println("requestID : " + ex.getRequestId());
		}

		return empList;
	}
	
	private Employee createEmployee(Item item) throws SDBException {
		Employee result = createEmployee(item.getAttributes());
		result.setId(item.getIdentifier());
		return result;
	}
	
	private Employee createEmployee(List<ItemAttribute> attList) {
		
		Employee result = new Employee();
		
		for (ItemAttribute att : attList) {
			String name = att.getName();
			String value = att.getValue();
			if ("firstname".equals(name)) {
				result.setFirstname(value);
			} else if ("lastname".equals(name)) {
				result.setLastname(value);
			} else if ("department".equals(name)) {
				Department dep = depDao.findDepartment(value);
				result.setDepartment(dep);
			}
		}
		return result;
	}
	
	public void setAwsAccessId(String value) {
		this.awsAccessId = value;
	}

	public void setAwsSecretKey(String value) {
		this.awsSecretKey = value;
	}

	public void setDepartmentDao(DepartmentDao depaDao) {
		this.depDao = depaDao;
	}
}
